﻿using Application.Common.Interface;
using AutoMapper;
using Core.Extensions;
using Domain.Dto.Selectors;
using Domain.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace Web.Controllers
{
    public class SelectorController : Controller
    {
        private readonly ILogger<SelectorController> logger;
        private readonly IMapper mapper;
        private readonly ISiteMapRepository siteMapRepository;
        private readonly ISelectorRepository selectorRepository;
        public SelectorController(ILogger<SelectorController> logger, IMapper mapper, ISelectorRepository selectorRepository, ISiteMapRepository siteMapRepository)
        {
            this.logger = logger;
            this.mapper = mapper;
            this.selectorRepository = selectorRepository;
            this.siteMapRepository = siteMapRepository;
        }
        public async Task<IActionResult> Add(int siteMapId,int fatherId)
        {
            var sel = await selectorRepository.GetBySiteMapIdAsync(siteMapId);
            if (sel is null)
                return NotFound();
            var siteMap = await siteMapRepository.GetAsync(siteMapId);
            if (siteMap is null) return NotFound();
            ViewData["SiteMapName"] = siteMap.Name;
            ViewData["SiteMapId"] = siteMap.Id;
            ViewBag.url = siteMap.Url;
            ViewBag.siteMapId = siteMapId;
            ViewBag.fatherId = fatherId;
            ViewBag.SelectList = await GetListItemBySiteMapIdAsync(siteMapId);
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Add(SelectorRequestDto dto)
        {
            await selectorRepository.AddAsync(mapper.Map<Selector>(dto));
            return RedirectToAction(nameof(Detail), new { siteMapId = dto.siteMapId, Id = dto.FatherId });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="siteMapId">暂时不能为0</param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Detail(int siteMapId,int Id)
        {
            if (siteMapId == default)
                return NotFound();
            var res = new SelectorResponseDto();
            var siteMap = await siteMapRepository.GetAsync(siteMapId);
            if (siteMap is null)
            {
                return NotFound();
            }
            res.Url = siteMap.Url;
            //_root元素
            if (Id == default)
            {
                var _root = await selectorRepository.GetBySiteMapIdAsync(siteMapId);
                if (_root is null)
                    return NotFound();
                res.Selector = _root;
                res.BreadCrumb = await GetBreadCrumb(_root);
                res.Childrens = await selectorRepository.GetChildrenSelectorsByFatherIdAsync(_root.Id);
            }
            else
            {
                var sel = await selectorRepository.GetByIdAsync(Id);
                if (sel is null)
                    return NotFound();
                res.Selector = sel;
                res.BreadCrumb = await GetBreadCrumb(sel);
                res.Childrens = await selectorRepository.GetChildrenSelectorsByFatherIdAsync(sel.Id);
            }
            ViewData["SiteMapName"] = siteMap.Name;
            ViewData["SiteMapId"] = siteMap.Id;
            return View(res);
        }

        public async Task<IActionResult> Edit(int Id)
        {
            var model = await selectorRepository.GetByIdAsync(Id);
            if (model is null) return NotFound();
            var selectNames=new List<SelectListItem>();
            var parentNames = model.ParentSelectorNames.StringSplitGetList<string>();
            var everyNames = await GetListItemBySiteMapIdAsync(model.SiteMapId);
            foreach (var it in everyNames)
            {
                if (parentNames.Contains(it.Value))
                    selectNames.Add(new() { Value = it.Value, Text = it.Text, Selected = true });
                else
                    selectNames.Add(new() { Value = it.Value, Text = it.Text, Selected = false });
            }
            ViewBag.SelectList = selectNames;
            var siteMap = await siteMapRepository.GetAsync(model.SiteMapId);
            ViewData["SiteMapName"] = siteMap.Name;
            ViewData["SiteMapId"] = siteMap.Id;
            return View(model);
        }
        [HttpPost]
        public async Task<IActionResult> Edit(Selector sel)
        {
            await selectorRepository.UpdateAsync(sel);
            return RedirectToAction(nameof(Detail), new { sel.SiteMapId, Id = sel.FatherId });
        }

        public async Task<IActionResult> Delete(int Id)
        {
            var sel = await selectorRepository.GetByIdAsync(Id);
            if (sel is null)
                return NotFound();
            await selectorRepository.DeleteAsync(Id);
            return RedirectToAction(nameof(Detail), new { sel.SiteMapId, Id = sel.FatherId });
        }
        private async Task<List<SelectListItem>> GetListItemBySiteMapIdAsync(int siteMapId)
        {
            var childrens = await selectorRepository.GetAllBySiteMapIdAsync(siteMapId);
            var childNames = childrens.Select(c => c.Name).Distinct();
            var selectList = new List<SelectListItem>();
            foreach (var it in childNames)
            {
                if (it == "_root")
                    selectList.Add(new() { Selected = true, Text = it, Value = it });
                else
                    selectList.Add(new() { Text = it, Value = it });
            }
            return selectList;
        }
        private async Task<List<Selector>> GetBreadCrumb(Selector sel)
        {
            var res = new List<Selector>();
            var parents = await selectorRepository.GetParentSelectorsBySelectorAsync(sel);
            res.AddRange(parents);
            res.Add(sel);
            return res;
        }
    }
}
